<!DOCTYPE html>
<html>
<head>
<title>jQuery学习笔记</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
html,
body,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
ol,
ul,
li,
img {
    margin: 0;
    padding: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
}

html * {
    font-family: "ff-din-web-pro-1", "ff-din-web-pro-2", sans-serif;
    font-size: 16px;
    line-height: 19.2px;
    color-profile: sRGB;
}

body {
    min-width: 32em;
    max-width: 56em;
    margin: 10px auto;
}

p, blockquote p {
    line-height: 1.6;
}

ul, ol {
    margin: 16px 0;
}

ul li, ol li {
    line-height: 1.6;
}

p {
    font-weight: lighter;
    margin: 10px 0;
}

strong {
    font-weight: bold;
}

ol,
ul {
    margin-left: 2em;
}

h1,
h2,
h3,
h4,
h5,
h6 {
    font-weight: lighter;
    text-transform: capitalize;
    margin: 20px 0;
    border-bottom: 1px solid;
    padding-bottom: 6px;
}

h1, h1 > code {
    font-size: 24.624px;
    line-height: 29.548799999999996px;
}

h2, h2 > code {
    font-size: 24.624px;
    line-height: 29.548799999999996px;
}

h3, h3 > code {
    font-size: 23.44px;
    line-height: 28.128px;
}

h4, h4 > code {
    font-size: 22.16px;
    line-height: 26.592px;
}

h5, h5 > code {
    font-size: 22.16px;
    line-height: 26.592px;
}

h6, h6 > code {
    font-size: 22.16px;
    line-height: 26.592px;
}

img {
    margin-bottom: 20px;
}

h1 img,
h2 img,
h3 img,
h4 img,
h5 img,
h6 img,
p img {
    margin-bottom: 0;
}

pre,
code {
    font-family: monospace, Consolas, "Source Code Pro", Arial, sans-serif;
    color: #586e75;
    background-color: #eee8d5;
}

pre {
    white-space: pre-wrap;
    word-wrap: break-word;
    padding: 12px;
    margin-bottom: 20px;
}

code {
    border-radius: 3px;
}

h1 {
    text-transform: uppercase;
    font-weight: bold;
}

h3,
h4,
h5,
h6 {
    border-bottom: none;
}

html body {
    background-color: #fdf6e3;
}

html h1,
html h2,
html h3,
html h4,
html h5,
html h6 {
    color: #586e75;
    border-color: #657b83;
}

html a,
html a:active,
html a:visited {
    color: #586e75;
    text-decoration: none;
    border-bottom: 1px dashed;
    border-radius: 2px;
}

html a:hover {
    background-color: #eee8d5;
}

blockquote a:hover {
    background-color: #fdf6e3;
}

html a,
html a:active,
html a:visited,
html code.url {
    color: #b58900;
}

html h1 {
    color: #b58900;
}

html h2,
html h3,
html h4,
html h5,
html h6 {
    color: #b58900;
}

/* QUOTES
=============================================================================*/
blockquote {
    border-left: 4px solid #b58900;
    padding: 12px;
    background: #eee8d5;
    border-bottom-right-radius: 2px;
}

blockquote code {
    background: #fdf6e3;
}

blockquote > :first-child {
    margin-top: 0;
}

blockquote > :last-child {
    margin-bottom: 0;
}

/* TABLES
=============================================================================*/
table {
    margin: 0 auto;
    border-collapse: collapse;
    width: 100%;
    box-sizing: border-box;
    margin-bottom: 30px;
}

table th, table td {
    border: 1px solid #ccc;
    padding: 6px 13px;
}

table td {
    word-break: break-word;
    line-height: 1.3;
}

table th {
    font-weight: bold;
    text-align: center !important;
    background-color: #eee8d5;
}

table tr {
    border-top: 1px solid #ccc;
    background-color: #fdf6e3;
}

/* IMAGES
=============================================================================*/
img {
    max-width: 100%;
}

p > img {
    display: table;
    margin: 0 auto;
}

p code, li code, td code {
    padding: 1px 3px;
    border-radius: 3px;
}

.cp_embed_wrapper {
    margin: 20px 0;
}

.hljs {
	background: #eee8d5 !important;
}

@media screen and (min-width: 980px) and (max-width: 980px) {	
    table thead tr th,
    table thead tr th > code,
    table tbody tr td,
    table tbody tr td > code,
    table tbody tr td > strong {
        font-size: 1.3em;
        line-height: 1.3;
    }

    p, p code,
    p strong, p strong > code,
    blockquote p {
        font-size: 1.3em;
        line-height: 1.6;
    }

    pre > code,
    ul li pre > code,
    ol li pre > code{
		font-size: 1.3em;
        line-height: 1.3;    	
    }	
	

    ul li, ol li,
    ul li > code,
    ol li > code {
        font-size: 1.3em;
		line-height: 1.3;          
    }

    ul {
        margin-left: 3.4em;
    }

    ol {
        margin-left: 3.6em;
    }
}
</style>
<style type="text/css">
.highlight  { background: #ffffff; }
.highlight .c { color: #999988; font-style: italic } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { font-weight: bold } /* Keyword */
.highlight .o { font-weight: bold } /* Operator */
.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #999999 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #aaaaaa } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { font-weight: bold } /* Keyword.Constant */
.highlight .kd { font-weight: bold } /* Keyword.Declaration */
.highlight .kp { font-weight: bold } /* Keyword.Pseudo */
.highlight .kr { font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #009999 } /* Literal.Number */
.highlight .s { color: #d14 } /* Literal.String */
.highlight .na { color: #008080 } /* Name.Attribute */
.highlight .nb { color: #0086B3 } /* Name.Builtin */
.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
.highlight .no { color: #008080 } /* Name.Constant */
.highlight .ni { color: #800080 } /* Name.Entity */
.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
.highlight .nn { color: #555555 } /* Name.Namespace */
.highlight .nt { color: #000080 } /* Name.Tag */
.highlight .nv { color: #008080 } /* Name.Variable */
.highlight .ow { font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mf { color: #009999 } /* Literal.Number.Float */
.highlight .mh { color: #009999 } /* Literal.Number.Hex */
.highlight .mi { color: #009999 } /* Literal.Number.Integer */
.highlight .mo { color: #009999 } /* Literal.Number.Oct */
.highlight .sb { color: #d14 } /* Literal.String.Backtick */
.highlight .sc { color: #d14 } /* Literal.String.Char */
.highlight .sd { color: #d14 } /* Literal.String.Doc */
.highlight .s2 { color: #d14 } /* Literal.String.Double */
.highlight .se { color: #d14 } /* Literal.String.Escape */
.highlight .sh { color: #d14 } /* Literal.String.Heredoc */
.highlight .si { color: #d14 } /* Literal.String.Interpol */
.highlight .sx { color: #d14 } /* Literal.String.Other */
.highlight .sr { color: #009926 } /* Literal.String.Regex */
.highlight .s1 { color: #d14 } /* Literal.String.Single */
.highlight .ss { color: #990073 } /* Literal.String.Symbol */
.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #008080 } /* Name.Variable.Class */
.highlight .vg { color: #008080 } /* Name.Variable.Global */
.highlight .vi { color: #008080 } /* Name.Variable.Instance */
.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
.pl-c {
    color: #969896;
}

.pl-c1,.pl-mdh,.pl-mm,.pl-mp,.pl-mr,.pl-s1 .pl-v,.pl-s3,.pl-sc,.pl-sv {
    color: #0086b3;
}

.pl-e,.pl-en {
    color: #795da3;
}

.pl-s1 .pl-s2,.pl-smi,.pl-smp,.pl-stj,.pl-vo,.pl-vpf {
    color: #333;
}

.pl-ent {
    color: #63a35c;
}

.pl-k,.pl-s,.pl-st {
    color: #a71d5d;
}

.pl-pds,.pl-s1,.pl-s1 .pl-pse .pl-s2,.pl-sr,.pl-sr .pl-cce,.pl-sr .pl-sra,.pl-sr .pl-sre,.pl-src,.pl-v {
    color: #df5000;
}

.pl-id {
    color: #b52a1d;
}

.pl-ii {
    background-color: #b52a1d;
    color: #f8f8f8;
}

.pl-sr .pl-cce {
    color: #63a35c;
    font-weight: bold;
}

.pl-ml {
    color: #693a17;
}

.pl-mh,.pl-mh .pl-en,.pl-ms {
    color: #1d3e81;
    font-weight: bold;
}

.pl-mq {
    color: #008080;
}

.pl-mi {
    color: #333;
    font-style: italic;
}

.pl-mb {
    color: #333;
    font-weight: bold;
}

.pl-md,.pl-mdhf {
    background-color: #ffecec;
    color: #bd2c00;
}

.pl-mdht,.pl-mi1 {
    background-color: #eaffea;
    color: #55a532;
}

.pl-mdr {
    color: #795da3;
    font-weight: bold;
}

.pl-mo {
    color: #1d3e81;
}
.task-list {
padding-left:10px;
margin-bottom:0;
}

.task-list li {
    margin-left: 20px;
}

.task-list-item {
list-style-type:none;
padding-left:10px;
}

.task-list-item label {
font-weight:400;
}

.task-list-item.enabled label {
cursor:pointer;
}

.task-list-item+.task-list-item {
margin-top:3px;
}

.task-list-item-checkbox {
display:inline-block;
margin-left:-20px;
margin-right:3px;
vertical-align:1px;
}
</style>
<base target=_blank>
<meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1">
<meta name="keywords" content="whjin,前端开发文档,html,css,javascript,canvas,jquery,vue.js,http,ajax,git,webpack">
<meta name="format-detection" content="telephone=no">
<meta name="description" content="前端开发文档">
<meta name="author" content="whjin">
<link rel="shortcut icon" href="https://whjin.github.io/frontend-dev-doc/images/logo.png">
<a href="https://github.com/whjin" class="github-corner" aria-label="View source on GitHub" target="_blank"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: fixed; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
<link href="https://cdn.bootcss.com/highlight.js/9.15.6/styles/a11y-light.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/highlight.js/9.15.6/highlight.min.js"></script>
<script >hljs.initHighlightingOnLoad();</script> 
</head>
<body>
<h1 id="jquery-">jQuery学习笔记</h1>
<p>jQuery大部分功能需要根据文档的DOM模型来工作，首先需要正确地解析到整个文档的DOM模型结构。使用jQuery需要在整个文档被浏览器完全加载后才开始进行。</p>
<pre><code>$(document).ready(function () {
    alert(&quot;Hello World!&quot;);
    $(&quot;p&quot;).click(function (event) {
        alert(&quot;Thanks for visiting!&quot;);
    })
});
</code></pre><p><code>$</code>是在jQuery中使用的变量名，可以使用<code>jQuery.noConflict()</code>避免冲突，它的返回值就是jQuery对象。</p>
<pre><code>jQuery.noConflict();
$j = jQuery.noConflict();
</code></pre><p><strong>jQuery对象与DOM对象之间的转换</strong></p>
<p>使用<code>$()</code>得到的是一个jQuery对象。它封装了很多 DOM 对象的操作，但是它和 DOM 对象之间是不同的。只有当<code>obj</code>是一个DOM对象时才能使用<code>obj.innerHTML</code>；相应地，如果是jQuery对象应该使用 <code>obj.html()</code> 。</p>
<ul>
<li>从 DOM 对象转到 jQuery 对象： <code>$(obj)</code> </li><li>从 jQuery 对象转到 DOM 对象： <code>obj[0]</code></li></ul>
<p>比较正规地从 jQuery 对象到 DOM 的转换，是使用 jQuery 对象的 <code>get()</code> 方法：</p>
<pre><code>$(function () {
    $(&quot;li&quot;).get();
    $(&quot;li&quot;).get(0);
    $(&quot;li&quot;).get(-1);
});
</code></pre><h2 id="jquery-">jQuery选择器</h2>
<p><strong>1. 常规选择器</strong></p>
<ul>
<li><code>$(&quot;*&quot;)</code> 选择所有节点</li><li><code>$(&quot;#id&quot;)</code> ID选择器，注意其中的一些特殊字符，如<code>.</code></li><li><code>$(&quot;.class&quot;)</code> 类选择器</li><li><code>$(&quot;tag&quot;)</code> 标签选择器</li><li><code>$(&quot;子元素&quot;)</code> </li><li><code>$(&quot;直接子元素&quot;)</code> </li><li><code>:focus</code> 获取焦点元素</li><li><code>:first-child/:last-child</code> 选择第一个/最后一个元素 </li><li><code>:first/:last</code> 截取第一个/最后一个符合条件的元素</li><li><code>(&quot;pre+next&quot;)</code> 直接兄弟元素</li><li><code>(&quot;pre~siblings&quot;)</code> 兄弟元素</li><li><code>:nth-child()</code> 索引选择，索引从1开始<ul>
<li><code>:nth-child(odd)</code></li><li><code>:nth-child(even)</code></li><li><code>:nth-child(4n)</code></li></ul>
</li></ul>
<p><strong>2. 属性选择器</strong></p>
<ul>
<li><code>[name~=&quot;value&quot;]</code> 属性中包括某单词  </li><li><code>[name=&quot;value&quot;]</code> 属性完全等于指定值</li><li><code>[name!=&quot;value&quot;]</code> 属性不等于指定值</li><li><code>[name]</code> 包括有指定属性的元素</li></ul>
<p><strong>3. 控件选择器</strong></p>
<ul>
<li><code>:checked</code> 选择所有被选中的元素</li><li><code>:selected</code> 被选择的元素</li><li><code>:disabled/:enabled</code> 选择被禁用/未禁用的元素</li><li><code>:hidden</code> 隐藏元素，不仅是<code>[type=&quot;hidden&quot;]</code>，还有<code>displa:none</code></li><li><code>:visible</code> 可见控件，<code>visibility:hidden</code>和<code>opacity:0</code>同样被认为是可见</li><li><code>:input :button :checkbox :file :image :password :radio :reset :submit :text</code> 具体控件，图像控件是<code>[type=&quot;image&quot;]</code> </li></ul>
<p><strong>4. 其他选择器</strong></p>
<ul>
<li><code>[name=&quot;value&quot;] [name2=&quot;value2&quot;]</code> 多个AND条件  </li><li><code>(&quot;selector1, selector2, selectorN&quot;)</code> 多个OR条件</li><li><code>:not()</code> 否定选择 </li><li><code>(&#39;:contains(&quot;text&quot;)&#39;)</code> 包含有指定内容的元素 </li><li><code>:eq() :lt() :gt() :even :odd</code> 列表索引选择（不支持负数）</li><li><code>(&#39;:has(selector)&#39;)</code> 符合条件的再次过滤</li><li><code>:header</code> 选择<code>h1,h2,h3...</code>标题元素</li><li><code>:only-child</code> 仅有一个子元素的元素</li><li><code>:empty</code> 空元素，即无内容也无元素</li><li><code>:parent</code> 非空元素</li></ul>
<h2 id="-">节点漫游</h2>
<p><strong>1. 调用链处理</strong></p>
<ul>
<li><code>.add()</code> 向已有的节点序列中添加新的对象 </li><li><code>.andSelf()</code> 在调用链中，随时加入原始序列</li><li><code>.eq()</code> 指定索引选取节点，支持负数</li><li><code>.filter() .is() .not() .find() .first() .last() .has()</code> 序列选择</li><li><code>.end()</code> 节点回溯</li></ul>
<pre><code>$(function () {
    $(&#39;ul.first&#39;).find(&#39;.foo&#39;).css(&#39;background-color&#39;, &#39;red&#39;)
        .end().find(&#39;.bar&#39;).css(&#39;background-color&#39;, &#39;green&#39;);
});
</code></pre><p><strong>2. 子节点</strong></p>
<ul>
<li><code>.children()</code> 所有的子节点，可加入过滤条件，<code>.children(selector)</code></li></ul>
<p><strong>3. 兄弟节点</strong></p>
<ul>
<li><code>.siblings() .next() .nextAll() .nextUntil() .prevAll() .prevUntil() .closet()</code> 选择兄弟节点</li></ul>
<p><strong>4. 父节点</strong></p>
<ul>
<li><code>.parent() .parents() .parentUntil()</code> 父节点选择</li></ul>
<h2 id="-">元素控制</h2>
<p><strong>1. <code>attributes</code>和<code>properties</code>的区别</strong></p>
<ul>
<li><code>attributes</code> 是XML结构中的属性节点 <ul>
<li><code>&lt;div onload=&quot;prettyPrint()&quot;&gt;&lt;/div&gt;</code></li></ul>
</li><li><code>properties</code> 是DOM对象，对象属性<ul>
<li><code>$(&#39;body&#39;).get(0).tagName;</code></li></ul>
</li></ul>
<p><strong>2. 类与属性控制</strong></p>
<ul>
<li><code>.addCLass() .hasClass() .removeClass()</code> 添加一个类，判断是否有指定类，删除类</li></ul>
<pre><code>$(&#39;body&#39;).addClass(&#39;test&#39;);
$(&#39;body&#39;).addClass(function (index, current) {
    return current + &#39;new&#39;;
});
$(&#39;body&#39;).removeClass(&#39;test&#39;);
$(&#39;body&#39;).removeClass(function (index, current) {
    return current + &#39; &#39; + &#39;other&#39;;
});
</code></pre><ul>
<li><code>.toggleClass()</code> 类的开关式转换</li></ul>
<pre><code>$(&#39;img&#39;).toggleClass(); //对所有类的开关
$(&#39;img&#39;).toggleClass(&#39;test&#39;); //对指定类的开关
$(&#39;img&#39;).toggleClass(isTrue); //根据`isTrue`判断所有类的开关
$(&#39;img&#39;).toggleClass(&#39;test&#39;, isTrue); //根据`isTrue`判断指定类的开关

//同 `$(&#39;img&#39;).toggleClass(&#39;test&#39;);` 只是类名由函数返回
$(&#39;img&#39;).toggleClass(function (index, className, isTrue) {
    return &#39;name&#39;
});

// `isTrue`作为函数的第三个参数传入
$(&#39;img&#39;).toggleClass(function (index, className, isTrue) {
    return &#39;name&#39;
}, isTrue);
</code></pre><ul>
<li><code>.attr()</code> 获取或设置一个属性值</li></ul>
<pre><code>// $(&quot;#greatphoto&quot;).attr(&#39;alt&#39;); //获取属性`
$(&quot;#greatphoto&quot;).attr(&#39;alt&#39;, &#39;Shenzhen Brush Seller&#39;); //设置属性`

// 同时设置多个属性
$(&#39;#greatphoto&#39;).attr({
    alt: &#39;Shen Brush Seller&#39;,
    title: &#39;photo by Kelly Clark&#39;
});

//设置属性为函数返回值，函数的上下文为当前元素
$(&#39;#greatphoto&#39;).attr(&#39;title&#39;, function (i, val) {
    return val + &#39; - photo by Kelly Clark&#39;;
})
</code></pre><ul>
<li><code>.prop()</code> 用法同<code>.attr()</code>，只是对象变成了<code>properties</code></li><li><code>.removeAttr() .removeProp()</code> 删除属性</li><li><code>.val()</code> 设置或获取元素的表单值，通常用于表单元素</li></ul>
<pre><code>$(&#39;input&#39;).val();
$(&#39;input&#39;).val(&#39;other&#39;);
</code></pre><ul>
<li><code>.html()</code> 设置或获取元素的节点<code>html</code></li></ul>
<pre><code>$(&#39;div&#39;).html();
$(&#39;div&#39;).html(&#39;&lt;div&gt;测试&lt;/div&gt;&#39;);
$(&#39;div&#39;).html(function (index, old) {
    return old + &#39;&lt;span&gt;另外的内容&lt;/span&gt;&#39;;
});
</code></pre><p><strong>3. 样式控制</strong></p>
<ul>
<li><code>.css()</code> 获取或设置指定的CSS样式</li></ul>
<pre><code>$(&#39;body&#39;).css(&#39;background-color&#39;, &#39;red&#39;);
$(&#39;body&#39;).css(&#39;background-color&#39;, function (index, value) {
    return value + &#39;1&#39;;
});
$(&#39;body&#39;).css({color: &#39;green&#39;, &#39;background-color&#39;: &#39;red&#39;});
</code></pre><ul>
<li><code>.width() .height()</code> 获取或设置元素的宽和高</li></ul>
<pre><code>$(&#39;body&#39;).width();
$(&#39;body&#39;).width(50);
$(&#39;body&#39;).width(function (index, value) {
    return value += 10;
})
</code></pre><ul>
<li><code>.innerWidth() .innerHeight() .outerHeight() .outerWidth()</code> 元素的其他尺寸值</li><li><code>.scrollLefgt() .scrollTop()</code> 获取或设置滚动条的位置</li><li><code>.offset() .position()</code> 获取元素的坐标<ul>
<li><code>offset</code>是相对于<code>document</code>，<code>position</code>是相对于父级元素</li></ul>
</li></ul>
<p><strong>结构控制</strong></p>
<p><strong>1. 文本节点</strong></p>
<ul>
<li><code>.html() .text()</code> 设置和获取节点的文本值。设置时<code>.text()</code>会转义标签，获取时<code>.text()</code>会移除所有标签。</li></ul>
<p><strong>2. 子节点</strong></p>
<ul>
<li><code>.append() .prepend()</code></li></ul>
<pre><code>$(&#39;.inner&#39;).append(&#39;&lt;p&gt;Test&lt;/p&gt;&#39;);
</code></pre><p>参数可以有多种形式：</p>
<pre><code>var $newdiv1 = $(&#39;&lt;div id=&quot;object1&quot;/&gt;&#39;),
    newdiv2 = document.createElement(&#39;div&#39;),
    existingdiv1 = document.getElementById(&#39;foo&#39;);

$(&#39;body&#39;).append($newdiv1, [newdiv2, existingdiv1]);
</code></pre><p><strong>3. 兄弟节点</strong></p>
<ul>
<li><code>.after() .before()</code></li></ul>
<pre><code>$(&#39;.inner&#39;).after(&#39;&lt;p&gt;Test&lt;/p&gt;&#39;);
</code></pre><p><strong>4. 父节点</strong></p>
<ul>
<li><code>.wrap() .wrap() .wrapInner()</code></li></ul>
<pre><code>$(&#39;.inner&#39;).wrap(&#39;&lt;div class=&quot;new&quot;&gt;&lt;/div&gt;&#39;);
$(&#39;.inner&#39;).wrapAll(&#39;&lt;div class=&quot;new&quot;&gt;&lt;/div&gt;&#39;);
$(&#39;.inner&#39;).wrapInner(&#39;&lt;div class=&quot;new&quot;&gt;&lt;/div&gt;&#39;);
</code></pre><p><strong>5. 复制/删除/替换节点</strong></p>
<ul>
<li><code>.clone()</code> 复制节点，可选参数表示是否处理已绑定的事件与数据<ul>
<li><code>.clone(true)</code> 处理当前节点的事件与数据</li><li><code>.clone(true, true)</code> 处理当前节点及所有子节点的事件与数据</li></ul>
</li><li><code>.detach()</code> 暂时移除节点，之后可以再次恢复指定位置</li><li><code>.remove()</code> 永久移除节点</li><li><code>.empty()</code> 清除一个节点的所有内部内容</li><li><code>.unwrap()</code> 移除节点的父节点</li></ul>
<h2 id="-">工具函数</h2>
<ul>
<li><code>.map()</code> 遍历所有成员</li></ul>
<pre><code>$(&#39;:checkbox&#39;).map(function () {
    return this.id;
}).get().join(&#39;,&#39;);

$(&#39;:checkbox&#39;).map(function (index, node) {
    return node.id;
}).get().join(&#39;,&#39;);
</code></pre><ul>
<li><code>.slice()</code> 序列切片，支持一个或两个参数，支持负数</li></ul>
<pre><code>$(&#39;li&#39;).slice(2).css(&#39;background-color&#39;, &#39;red&#39;);
$(&#39;li&#39;).slice(2, 4).css(&#39;background-color&#39;, &#39;green&#39;);
$(&#39;li&#39;).slice(-2, -1).css(&#39;background-color&#39;, &#39;blue&#39;);
</code></pre><h2 id="-">通用工具</h2>
<ul>
<li><code>$.each() $.map()</code> 遍历列表，<code>$.map()</code>可以用于对象</li></ul>
<pre><code>$.each([52, 97], function (index, value) {
    console.log((index + &#39; : &#39; + value));
});
$.map([0, 1, 2], function (index, n) {
    return n + 4;
});
$.map([0, 1, 2], function (n) {
    return n &gt; 0 ? n + 1 : null;
});
$.map([0, 1, 2], function (n) {
    return [n, n + 1];
});

var dimensions = {width: 10, height: 15, length: 20};
$.map(dimensions, function (value, key) {
    return value * 2;
});

var dimensions = {width: 10, height: 15, length: 20};
$.map(dimensions, function (value, key) {
    return key;
});
</code></pre><ul>
<li><code>$.extend()</code> 合并对象，第一个参数表示是否进行递归深入</li></ul>
<pre><code>var object = $.extend({}, object1, object2);
var object = $.extend(true, {}, object1, object2);
</code></pre><ul>
<li><code>$.merge()</code> 合并列表</li></ul>
<pre><code>$.merge([0, 1, 2], [2, 3, 4]);
</code></pre><ul>
<li><code>.grep()</code> 过滤列表，第三个参数表示是否为取反</li></ul>
<pre><code>$.grep([0, 1, 2], function (array, index) {
    return n &gt; 0;
});//[1,2]
$.grep([0, 1, 2], function (array, index) {
    return n &gt; 0;
}, true);//[0]
</code></pre><ul>
<li><code>$.inArray()</code> 存在判断</li></ul>
<pre><code>$.inArray(value, array [, fromIndex])
</code></pre><ul>
<li><code>$.isArray() $.isEmptyObject() $.isFunction() $.iSNumeric() $.isPainObject() $.isWindow $.isXMLDoc()</code> 类型判断</li><li><code>$.noop()</code> 空函数</li><li><code>$.now()</code> 当前时间戳，值为<code>(new Date).getTime()</code></li><li><code>$.parseJson() $.parseXML()</code> 把字符串解析为对象</li></ul>
<pre><code>var xml = &quot;&lt;rss version=&#39;2.0&#39;&gt;&lt;channel&gt;&lt;title&gt;RSS Title&lt;/title&gt;&lt;/channel&gt;&lt;/rss&gt;&quot;,
    xmlDoc = $.parseXML(xml),
    $xml = $(xmlDoc),
    $title = $xml.find(&quot;title&quot;);
</code></pre><ul>
<li><code>$.trim()</code> 去头去尾 <code>$.trim(str)</code></li><li><code>$.type()</code> 判断参数的类型</li><li><code>$.unique()</code> 遍历后去重。<code>$.unique(arraty)</code></li></ul>
<h2 id="-">上下文绑定</h2>
<ul>
<li><code>$.proxy()</code> 为函数绑定上下文<ul>
<li><code>$.proxy(function,context)</code></li><li><code>$.proxy(context,name)</code></li></ul>
</li></ul>
<pre><code>var o = {
    x: &#39;123&#39;,
    f: function () {
        console.log(this.x)
    },
};
var go = function (f) {
    f()
};

o.f();// 123
go(o.f);// undefined
go($.proxy(o.f, o));//123
$.proxy(o, &#39;f&#39;)(); //123
</code></pre><p><strong>当一个函数被传递之后，它就失去了原先的上下文。</strong></p>
<h2 id="-">把数据存到节点中</h2>
<p>jQuery提供了一种机制，可以把节点作为数据存储的容器。</p>
<ul>
<li><code>$.data()</code> 往节点中获取/设置数据</li><li><code>$.removeData()</code> 删除数据</li></ul>
<p>在内部实现上，jQuery会在指定节点添加一个内部标识，以此为<code>key</code>，把数据存在内部闭包的一个结构中。</p>
<p>事实上，jQuery的事件绑定机制也使用了这套数据接口。</p>
<pre><code>$.data($(&#39;#data&#39;).get(0), &#39;test&#39;, &#39;123&#39;);
$(&#39;#data&#39;).data(&#39;test&#39;, &#39;456&#39;);
</code></pre><h2 id="-">事件处理</h2>
<p><strong>1. 事件绑定</strong></p>
<p>在 jQuery1.7之后，推荐统一使用<code>on()</code>来进行事件绑定。</p>
<ul>
<li><code>.on()</code> 绑定事件 <code>on()</code>的基本使用方式是：<code>.on(event,handler)</code></li><li><code>.off()</code> 移除事件</li><li><code>.one()</code> 绑定单次事件</li></ul>
<pre><code>$(&#39;#btn&#39;).on(&#39;click&#39;, function (eventObj) {
    console.log(&#39;Hello&#39;);
})
</code></pre><p>对于<code>handler</code>，它默认的上下文是触发事件的节点：</p>
<pre><code>$(&#39;#btn&#39;).on(&#39;click&#39;, function (eventObj) {
    console.log(this);
})
</code></pre><p>使用<code>$.proxy()</code>可以随意控制上下文：</p>
<pre><code>$(&#39;#btn&#39;).on(&#39;click&#39;,
    $.proxy(function (eventObj) {
        console.log(this.a);
    }, {a: 123})); // 123
</code></pre><p><code>event</code>参数还支持通过：</p>
<pre><code>- 以`.`分割的子名字
- 以空格分割的多个事件
</code></pre><pre><code>$(&#39;#btn&#39;).on(&#39;click.my&#39;, (function (eventObj) {
            console.log(&#39;123&#39;);
        }
    )
);
var f = function () {
    $(&#39;#btn&#39;).off(&#39;click.my&#39;)
};
</code></pre><p>多个事件：</p>
<pre><code>$(&#39;#btn&#39;).on(&#39;click.my click.other&#39;,
    (function (eventObj) {
            console.log(&#39;123&#39;);
        }
    )
);
var f = function () {
    $(&#39;#btn&#39;).off(&#39;click.my&#39;)
}
</code></pre><p><code>on()</code>的另一种调用形式：</p>
<pre><code>$(&#39;#btn&#39;).on({
    &#39;click&#39;: function (eventObj) {
        console.log(&#39;click&#39;);
    },
    &#39;mousemove&#39;: function (eventObj) {
        console.log(&#39;move&#39;);
    }
});
</code></pre><p><code>off()</code>的使用方式与<code>on()</code>完全类似：</p>
<pre><code>var f = function (eventObj) {
    console.log(&#39;Hello&#39;);
};
$(&#39;#btn&#39;).on(&#39;click&#39;, f);
$(&#39;#btn&#39;).off(&#39;click&#39;);
</code></pre><p><strong>2. 事件触发</strong></p>
<p>事件的触发有两种方式，一是使用预定的“事件函数”（<code>.click()</code>，<code>.focus()</code>），二是使用<code>trigger()</code>或<code>triggerHandler()</code>。</p>
<pre><code>$(&#39;#btn&#39;).on(&#39;click&#39;, function (eventObj) {
    console.log(&quot;hello&quot;);
});
$(&#39;#btn&#39;).click();
$(&#39;#btn&#39;).trigger(&#39;click&#39;);
</code></pre><p><code>trigger()</code>与<code>triggerHandler()</code>不同之处在于前面是触发事件，而后者是执行绑定函数。</p>
<pre><code>$(&#39;#btn&#39;).on(&#39;focus&#39;, function (event) {
    console.log(&quot;Hello&quot;);
});
$(&#39;#btn&#39;).triggerHandler(&#39;focus&#39;);
</code></pre><p><code>trigger()</code>和<code>triggerHandler()</code>也用于触发自定义事件。</p>
<pre><code>$(&#39;#btn&#39;).on(&#39;my&#39;, function (event) {
    console.log(&quot;Hello&quot;);
});
$(&#39;#btn&#39;).triggerHandler(&#39;my&#39;);
</code></pre><p><code>trigger()</code>和<code>triggerHandler()</code>触发事件时，可以带上参数：</p>
<pre><code>$(&#39;#btn&#39;).on(&#39;my&#39;, function (event) {
    console.log(obj);
});
$(&#39;#btn&#39;).trigger(&#39;my&#39;, {a: 123});
</code></pre><p><strong>3. 事件类型</strong></p>
<p>行为事件：</p>
<ul>
<li><code>.click()</code> 单击</li><li><code>.dbclick()</code> 双击</li><li><code>.blur()</code> 失去焦点时</li><li><code>.change()</code> 值变化时</li><li><code>.focus()</code> 获取焦点时</li><li><code>.focusin()</code> jQuery扩展的获取焦点</li><li><code>.focusout()</code> jQuery扩展的失去焦点</li><li><code>.resize()</code> 调整大小</li><li><code>.scroll()</code> 滚动</li><li><code>.select()</code> 被选择</li><li><code>.submit()</code> 表单被提交</li></ul>
<p>键盘事件：</p>
<ul>
<li><code>.keydown()</code> 按下键</li><li><code>.keyup()</code> 放开键</li></ul>
<p>鼠标事件：</p>
<ul>
<li><code>.mousedown()</code> 点下鼠标</li><li><code>.mouseup()</code> 松开鼠标</li><li><code>.mouseover()</code> 光标移入</li><li><code>.mouseout()</code> 光标移出</li><li><code>.mousemove()</code> 光标在其上移动</li><li><code>.mouseleave() .mouseenter()</code> 光标移出/移入</li></ul>
<p>页面事件：</p>
<ul>
<li><code>.ready()</code> 准备就绪</li><li><code>.unload()</code> 离开当前页时，针对<code>window</code>对象</li><li><code>.error()</code> 发生错误时</li><li><code>.load()</code> 正在载入</li></ul>
<p><strong>4. 事件对象</strong></p>
<ul>
<li><code>event.currentTarget,event,target</code> 事件绑定节点/事件的触发节点（冒泡行为）</li><li><code>event.delegateTarget</code> 绑定事件的对象，通常就是<code>event.currentTarget</code></li><li><code>event.relatedTarget</code> 相关的节点，主要用于一些转换式的事件。比如鼠标移入，表示它从哪个节点来的</li><li><code>event.which</code> 标明哪个按钮触发了事件，鼠标和键盘的键标识统一在这个属性中</li><li><code>event.preventDefault() event.isDefaultPrevented()</code> 禁止默认行为</li><li><code>event.stopImmediateProgation() event.isImmediateProgationStopped()</code> 不仅禁止冒泡。还终止绑定函数链的继续进行</li><li><code>event.stopPropagation()，event.isPropagationStopped()</code> 禁止冒泡</li><li><code>event.pageX，event.pageY</code> 事件触发时相对于<code>document</code>的鼠标位置</li><li><code>event.namespace</code> 事件触发时的名字空间，比如<code>trigger(&#39;click.namespace&#39;)</code> </li><li><code>event.data</code> 额外传入的数据</li><li><code>event.result</code> 上一个绑定函数的返回值</li><li><code>event.timeStamp</code> 事件触发时的时间，其值为<code>(new Date).getTime()</code></li><li><code>event.type</code> 事件类型</li></ul>
<p>如果一个绑定函数最后返回了<code>false</code>，则默认是<code>event.preventDefault()</code>和<code>event.stopPropagation()</code>行为。</p>
<h2 id="ajax">AJAX</h2>
<p><strong>1. 请求与回调</strong></p>
<p>jQuery的AJAX，核心的请求处理函数只有一个，就是<code>$.ajax()</code>，然后就是一个简单的上层函数。</p>
<p><code>$.ajax()</code> 的基本使用形式是：</p>
<p><code>jQuey.ajax(settings)</code> <code>settings</code>是一个对象，里面包含了所有的配置项。</p>
<ul>
<li><code>url</code> 请求的地址。</li><li><code>type</code> 请求的方法类型，<code>GET</code>，<code>POST</code>。默认是<code>GET</code>。</li><li><code>data</code> 要发送的数据</li><li><code>dataType</code> 服务器返回的数据类型，支持<code>xml</code>，<code>html</code>，<code>script</code>，<code>json</code>，<code>jsonp</code>，<code>text</code></li><li><code>success</code> 请求成功时调用的处理函数 <code>success(data, textStatus, jqXHR)</code></li><li><code>context</code> 回调函数执行时的上下文</li><li><code>cache</code> 默认为<code>true</code>，是否为请求单独添加一个随机参数以防止浏览器缓存</li><li><code>error</code> 请求错误时的调用函数。<ul>
<li><code>error(jqXHR, textStatus, errorThrown)</code></li><li>第二个参数是表示请求状态的字符串：<code>timeout</code>，<code>error</code>，<code>abort</code>，<code>parsererror</code></li><li>第三个参数是当HTTP错误发生时，具体的错误描述：<code>Not Found</code>，<code>Internal Server Error</code>等</li></ul>
</li><li><code>complete</code> 请求结束（无论成功或失败）时的一个回调函数。<ul>
<li><code>complete(jqXHR, textStatus)</code></li><li>第二个参数时表示请求状态的字符串：<code>success</code>，<code>notmodified</code>，<code>error</code>，<code>timeout</code>，<code>abort</code>，<code>parsererror</code>。</li></ul>
</li><li><code>jsonp</code> 一个参数名，默认是<code>callback</code>，一般用于指明回调函数名。设置成<code>false</code>可以让请求没有<code>callback</code>参数。</li><li><code>jsonpCallback</code> <code>callback</code>参数值。默认是自动生成的一个随机值。</li></ul>
<p><strong>2. 请求的状态</strong></p>
<p>对于全局的所有AJAX请求而言，可以在任意节点上绑定到全局任意AJAX请求的每一个事件：</p>
<pre><code>$(&#39;#loading&#39;).ajaxStart(function () {
    $(this).show();
});
</code></pre><ul>
<li><code>.ajaxStart()</code> 请求将要发出时</li><li><code>.ajaxSend()</code> 请求将要发出时（在<code>.ajaxStart()</code>后）</li><li><code>.ajaxSuccess()</code> 请求成功</li><li><code>.ajaxError()</code> 请求错误</li><li><code>.ajaxComplete()</code> 请求完成</li><li><code>.ajaxStop()</code> 请求结束（在<code>.ajaxComplete()</code>后）</li></ul>
<p><strong>3. 工具函数</strong></p>
<ul>
<li><code>.serialize()</code> 解析表单参数项，返回字符串</li></ul>
<pre><code>$(&#39;form&#39;).submit(function () {
    alert($(this).serialize());
    return false;
});
</code></pre><ul>
<li><code>.serializeArray()</code> 解析表单参数项，返回一个列表对象。</li></ul>
<pre><code>$(&#39;form&#39;).submit(function () {
    alert($(this).serializeArray());
    return false;
});
</code></pre><h2 id="-">泛化回调</h2>
<p><strong>1. <a href="https://whjin.github.io/full-stack-development/posts/JQ%E7%9A%84deferred%E5%AF%B9%E8%B1%A1.html">Deferred</a></strong></p>
<ul>
<li><code>Deferred</code>对象是在jQuery1.5中引入的回调管理对象。其作用是把一堆函数按顺序放入一个调用链，然后根据状态来依次调用这些函数。AJAX的所有操作都是使用它来进行封装的。</li></ul>
<pre><code>var obj = $.Deferred(function (a) {

});
obj.done(function () {
    console.log(&quot;1&quot;);
});
obj.done(function () {
    console.log(&quot;2&quot;);
});
obj.resolve();
</code></pre><p>总的来说：jQuery的<code>Deferred</code>对象有三个状态：<code>done</code>，<code>fail</code>，<code>process</code>。</p>
<pre><code>- `process` 只能先于其他两个状态先被激发。
- `done`和`fail`互斥，只能激发一个。
- `process`可以被重复激发，而`done`和`fail`只能激发一次。
</code></pre><p>然后，jQuery提供了一些函数用于添加回调，激发状态等。</p>
<ul>
<li><code>deferred.done()</code> 添加一个或多个成功回调</li><li><code>deferred.fail()</code> 添加一个或多个失败回调</li><li><code>deferred.always()</code> 添加一个函数，同时应用于成功和失败</li><li><code>deferred.progress()</code> 添加一个函数用于准备回调</li><li><code>deferred.then()</code> 依次接受三个函数，分别用于成功，失败，准备状态</li><li><code>deferred.reject()</code> 激发失败状态</li><li><code>deferred.resolve()</code> 激发成功状态</li><li><code>deferred.notify()</code> 激发准备状态</li></ul>
<p>如果一个<code>Deferred</code>已经被激发，则新添加的对应的函数会被立即执行。</p>
<p>jQuery还提供了一个<code>jQuery.when()</code>的回调管理函数，可以用于方便地管理多个事件并发的情况。</p>
<pre><code>var defer = $.ajax({
    url: &#39;test.html&#39;,
    dataType: &#39;json&#39;
});
defer.done(function (data) {
    console.log(data);
});
</code></pre><p><code>done()</code>做的事和使用<code>success()</code>定义是一样的。</p>
<p>当我们需要完成，像“请求A和请求B都完成时，执行函数”之类的需求时，使用<code>$.when()</code>就可以了。</p>
<pre><code>var defer_1 = $.ajax({
    url: &#39;json.html&#39;,
    dataType: &#39;json&#39;
});
var defer_2 = $.ajax({
    url: &#39;jsonp.html&#39;,
    dataType: &#39;jsonp&#39;
});
var new_defer = $.when(defer_1, defer_2);
new_defer.done(function () {
    console.log(&quot;hello&quot;);
});
</code></pre><p>在<code>$.when()</code>中的<code>Deferred</code>，只要有一个是<code>fail</code>，则整体结果为<code>fail</code>。</p>
<p><code>Deferred</code>的回调函数的执行顺序与它们的添加顺序一致。</p>
<p>这里特别注意一点，就是<code>done/fail/always</code>与<code>then</code>的返回值的区别。从功能上看，它们都可以添加回调函数，但是，方法的返回值是不同的。前组的返回值是原来的那个<code>defer</code>对象，而<code>then</code>返回的是一个新的<code>defer</code>对象。</p>
<p><code>then</code>返回新的<code>defer</code>这种形式，可以用于方便地实现异步函数的链式调用。</p>
<pre><code>defer.done(function () {
    return $.ajax({
        url: &#39;/json&#39;,
        dataType: &#39;json&#39;,
        success: function () {
            console.log(&quot;inner&quot;);
        }
    })
}).done(function () {
    console.log(&quot;hello&quot;);
});
</code></pre><p>等同于是调用了两次 <code>defer.done</code>, <code>defer.done</code> ，注册的两次回调函数依次被执行后，看到的输出是：<code>hello</code>，<code>inner</code>。</p>
<p>这是两次 <code>defer.done</code> 的结果，第一个回调函数返回了一个新的 <code>defer</code> 没任何作用。</p>
<p>如果换成 <code>then</code> 方法：<code>defer.then(function () {...});</code></p>
<p>它跟两次 <code>defer.done</code> 是不同的。 <code>new_defer</code> 会在 <code>inner</code> 那里的 <code>defer</code> 被触发时再被触发，所以输出结果是：<code>inner</code>，<code>hello</code>。</p>
<p>更一般地来说 <code>then</code> 的行为，就是前面的注册函数的返回值，会作为后面注册函数的参数值：</p>
<pre><code>var defer = $.ajax({
    url: &#39;/json&#39;,
    dataType: &#39;json&#39;
});
defer.then(function (res) {
    console.log(res);
    return 1;
}).then(function (res) {
    console.log(res);
    return 2;
}).then(function (res) {
    console.log(res);
});
</code></pre><p>上面代码的输入结果是：<code>ajax response</code>，<code>1</code>，<code>2</code>。</p>
<p><strong>2. Callbacks</strong></p>
<p>事实上，<code>Deferred</code>机制，只是在<code>Callbacks</code>机制的上层进行了一层简单封装。<code>Callbacks</code>对象才是真正的jQuery中定义的原始的回调管理机制。</p>
<pre><code>var obj = $.Callbacks();
obj.add(function () {
    console.log(&quot;1&quot;);
});
obj.add(function () {
    console.log(&quot;2&quot;);
});
obj.fire();
</code></pre><p><code>Callbacks</code>对象的初始化支持一组控制参数：</p>
<ul>
<li><code>$.Callbacks(flags)</code> 初始化一个回调管理对象。<code>flags</code>是空格分割的多个字符串，以定义此回调对象的行为：<ul>
<li><code>once</code> 回调链只能被激发一次</li><li><code>memory</code> 回调链被激发后，新添加的函数被立即执行</li><li><code>unique</code> 相同的回调函数只能被添加一次</li><li><code>stopOnFalse</code> 当有回调函数返回<code>false</code>时终止调用链的执行</li></ul>
</li></ul>
<p><code>CallbackS</code>的控制方法：</p>
<ul>
<li><code>callbacks.add()</code> 添加一个或一串回调函数</li><li><code>callbacks.fire()</code> 激发回调</li><li><code>callbacks.remove()</code> 从调用链中移除指定的函数</li><li><code>callbacks.empty()</code> 清空调用链</li><li><code>callbacks.disable()</code> 关闭调用链的继续执行，新添加的函数也不会被执行</li><li><code>callbacks.lock()</code> 锁定调用链，但是如果打开了<code>memory</code>的<code>flag</code>，新添加的函数仍然会执行</li><li><code>callbacks.has()</code> 检查一个函数是否处于回调链之中</li><li><code>callbacks.fired()</code> 检查回调链是否被激发</li><li><code>callbacks.locked()</code> 检查回调链是否被锁定</li></ul>

</body>
</html>
<!-- This document was created with MarkdownPad, the Markdown editor for Windows (http://markdownpad.com) -->
